/********************************************************************
 * Filename:	TestCommands.c
 * Description: The testing commands.
 * Group 2:		nachOS
 * Author(s):	Daniel Fairweather
 *              Ying Wang
 * Class:		CSE 325
 * Instructor:	David Duggan
 * Assignment:	Lab #8 File System Implementation
 * Assigned:	4/16/2013
 * Due:			4/30/2013
 ********************************************************************/

#include <stdio.h>
#include <string.h>
#include "TestCommands.h"

void init_fs(int device){
    int result = init_device(device);
    if(result == 0){
        printf("Device %i initialized.\n", device);
    }
    else if(result == -1){
        printf("Error: Device %i is already initialized.\n", device);
    }
    else if(result == -2){
	    printf("Error: Device ID must 0.\n");
    }
}


void list(){
	list_devices();
	printf("\n");
	list_directory();
	printf("\n");
}


void list_devices(){
	int i = 0;
	int count = 0;
	if(currently_mounted == -1){
        printf("Error: There are no mounted filesystems.\n");
        return;
    }
	for(i = 0; i < 1; i++){
		if(device_list[i] == 2 ){
			printf("Device %i has a valid file system.\n", i);
			count++;
		}
	}
	if(count == 0){
		printf("There is no device with a valid file system yet.\n");
	}
}


void list_file(char* filename){
	FCB temp;
    int blocknumber;

    if(currently_mounted == -1){
        printf("Error: There are no mounted filesystems.\n");
        return;
    }
	blocknumber = file_exists(filename);

    if(blocknumber == -1){
        printf("Error: File does not exists.\n");
        return;
    }

	print_FCB(blocknumber);
}


void list_file_bl(int blocknumber, int count){
	FCB temp;
	int i = 0;
	for(i = 0; i < count; i++){
		printf("\t");
	}	
	print_FCB(blocknumber);
}

void list_directory_bl(int blocknumber, int count){
	FCB fcb;
	int result;
	int i = 0;
	for(i = 0; i < count; i++){
		printf("\t");
	}
	print_FCB(blocknumber);

	i = 1;
    /* Loop through all indexes in the current directory. */
    while(1){
        result = read_address((SEGTYPE)blocknumber, i);

        /* If the block number returned is valid, get the FCB and print it. */
        if(result != 0){
            read_FCB(&fcb, result);
            if(fcb.isDirectory == 1){
				list_directory_bl(result, count+1);
            }
            else{
				list_file_bl(result, count+1);
            }
            i++;
        }
        /* If the block number is invalid, we have reached then end of the */
        else{
            break;
        }
    }
}


void list_directory(){
	FSIB fs;
	read_FSIB(&fs);
    if(currently_mounted == -1){
        printf("Error: There are no mounted filesystems.\n");
        return;
    }
    printf("Key: \033[35m{Block_Number}, \033[34mFile_Size \033[36m{Content_Blocks}\033[m\n\n");
	list_directory_bl(fs.root_block, 0);
}


void format(int device, char* fs_name, int blocksize){
    int result = format_fs(device, fs_name, blocksize);
    if(result == 0){
        printf("Filesystem %s (Device %i) has been formatted. It contains %i blocks.\n", fs_name, device, (DEVICE_SIZE/1024)/(blocksize));
    }
    else if(result == -1){
        printf("Error: Device ID must be 0.\n");
    }
    else if(result == -2){
        printf("Error: Device %i has not yet been initialized.\n", device);
    }
    else if(result == -3){
        printf("Error: Block size must be a number between 1 and 4.\n");
    }
}


void mount(char* fs_name){
	int result = mount_fs(fs_name);
	if(result == 0){
		printf("File system mounted.\n");
	}
	else if(result == -1){
		printf("Error: A file system is already mounted.\n");
	}
	else if(result == -2){
		printf("Error: No such file system exists.\n");
	}
	else if(result == -3){
		printf("Error: Device not formatted.\n");
	}
}


void unmount(char* fs_name){
	int result = unmount_fs(fs_name);
	if(result == 0){
		printf("File system unmounted.\n");
	}
	else if(result == -1){
		printf("Error: No file system is mounted.\n");
	}
	else if(result == -2){
		printf("Error: The file system is not currently mounted.\n");
	}
}


void open(char* filename, int mode){
    int result;

    /* New file. */
	if(mode == 0){
        result = create_file(filename, 0);
        if(result >= 0){
            printf("File created at block %i.\n", result);
        }
        else if(result == -1){
            printf("Error: There are no remaining blocks.\n");
        }
        else if(result == -2){
            printf("Error: Filename contains illegal characters.\n");
        }
        else if(result == -99){
            printf("Error: There are no mounted filesystems.\n");
        }
    }
	/* Open the file. */
	else{
		result = open_file(filename, mode);
		if(result >= 0){
			printf("The file has been opened. Filehandle is %i.\n", result);
		}
		else if(result == -1){
			printf("Error: The specified file doesn't exist.\n");
		}
		else if(result == -2){
			printf("Error: Too many files opened at the same time.\n");
		}
        else if(result == -99){
            printf("Error: There are no mounted filesystems.\n");
        }
	}
}


void read(int file_handle, int block_number, int buffer){
	int result = read_file(file_handle, block_number, buffer);
	if(result == 0){
		printf("The file content has been written to the buffer.\n");
	}
	else if(result == -1){
		printf("Error: The specified block is not in this file.\n");
	}
	else if(result == -2){
		printf("Error: The file is not open in read mode.\n");
	}
	else if(result == -3){
		printf("Error: The buffer address is not valid.\n");
	}
	else if(result == -4){
		printf("Error: The file handle is not valid.\n");
	}
    else if(result == -99){
        printf("Error: There are no mounted filesystems.\n");
    }
}


void write(int file_handle, int block_number, int buffer){
	int result = write_file(file_handle, block_number, buffer);
	if(result == 0){
		printf("The content of the buffer has been written to the block.\n");
	}
	if(result == 1){
		printf("The content of the buffer has been written to the block. File extended. \n");
	}
	else if(result == -1){
		printf("Error: The specified block is taken by another file.\n");
	}
	else if(result == -2){
		printf("Error: The file is not open in write mode.\n");
	}
	else if(result == -3){
		printf("Error: The buffer address is not valid.\n");
	}
	else if(result == -4){
		printf("Error: The file handle is not valid.\n");
	}
	else if(result == -5){
		printf("Error: add_address failed.\n");
	}
	else if(result == -6){
		printf("Error: The block number is not valid.\n");
	}
    else if(result == -99){
        printf("Error: There are no mounted filesystems.\n");
    }
}


void close(int filehandle){
	int result = close_file(filehandle);
	if(result == 0){
		printf("File closed.\n");
	}
	else if(result == -1){
		printf("Error: The file is already closed.\n");
	}
    else if(result == -99){
        printf("Error: There are no mounted filesystems.\n");
    }
}


void delete_File(char* filename){
	int result = delete_file(filename);
	if(result == 0){
		printf("File deleted.\n");
	}
	else if(result == -1){
		printf("Error: File does not exist.\n");
	}
    else if(result == -99){
        printf("Error: There are no mounted filesystems.\n");
    }
}


void ls(){
    int result;
    int i = 1;
    FCB fcb;

    if(currently_mounted == -1){
        printf("Error: There are no mounted filesystems.\n");
        return;
    }

    /* Loop through all indexes in the current directory. */
    while(1){
        result = read_address((SEGTYPE)current_directory, i);

        /* If the block number returned is valid, get the FCB and print it. */
        if(result != 0){
            read_FCB(&fcb, result);
            if(fcb.isDirectory == 0){
                printf("%s\t", fcb.filename);
            }
            else{
                printf("\033[35m%s/\033[m\t", fcb.filename);
            }
            i++;
        }
        /* If the block number is invalid, we have reached then end of the */
        else{
            printf("\n");
            break;
        }
    }
}


void mkdir(char* filename){
	int result = create_file(filename, 1);

    if(result >= 0){
        printf("Directory created at block %i.\n", result);
    }
    else if(result == -1){
        printf("Error: There are no remaining blocks.\n");
    }
    else if(result == -2){
            printf("Error: Directory contains illegal characters.\n");
        }
    else if(result == -99){
        printf("Error: There are no mounted filesystems.\n");
    }
}


void cd(char* directory_name){
	int result;
    
    if(strcmp(directory_name, "../") == 0){
        current_directory = read_address((SEGTYPE)current_directory, 0);
        return;
    }
    else if(strcmp(directory_name, "/") == 0){
        FSIB fsib;
        read_FSIB(&fsib);
        current_directory = fsib.root_block;
        return;
    }
    
    result = cd_directory(directory_name);

	if(result >= 0){
        printf("Entered directory. \n", result);
    }
    else if(result == -1){
        printf("Error: The specified directory doesn't exist.\n");
    }
    else if(result == -99){
        printf("Error: There are no mounted filesystems.\n");
    }
}


void print_FCB(int block){
    int i;
    int result;
    int first = 1;
    FCB fcb;
    int original_block = block;
    
    read_FCB(&fcb, block);

    if(fcb.isDirectory == 0){
        printf("\033[1m%s\033[m \033[35m{%i",fcb.filename,block);
        i = 0;
    }
    else{
        printf("\033[1m%s/\033[m \033[35m{%i",fcb.filename,block);
        i = 1;
    }

    /* Loop through all the indexes of the actual FCB */
    while(1){
        result = get_overflow_block(block);
        if(result == 0){
            break;
        }
        else{
            printf(", %i", result);
            block = result;
        }
        i++;
    }
    printf("}\033[m");

    block = original_block;

    printf(", \033[34m%i\033[m \033[36m{",fcb.filesize);
    /* Loop through all indexes in the current directory. */
    i = 1;
    if(fcb.isDirectory == 0){
        i = 0;
    }
    while(1){
        result = read_address((SEGTYPE)block, i);
        if(result == 0){
            break;
        }
        else{
            if(first == 1){
                printf("%i", result);
                first = 0;
            }
            else{
                printf(", %i", result);
            }
        }
        i++;
    }

    printf("}\033[m\n");
}